<template>
  <div class="view-wrapper">
    <el-form :inline="true" :model="formInline">
      <el-form-item label="选择摄像头">
        <el-select v-model="formInline.videoId" placeholder="摄像头">
          <el-option
            v-for="(item, index) in localDevice.videoIn "
            :key="index"
            :label="item.label"
            :value="item.id"
          />
        </el-select>
      </el-form-item>
      <el-form-item label="选择麦克风">
        <el-select v-model="formInline.audioInId" placeholder="麦克风">
          <el-option
            v-for="(item, index) in localDevice.audioIn "
            :key="index"
            :label="item.label"
            :value="item.id"
          />
        </el-select>
      </el-form-item>
      <el-form-item label="选择听筒">
        <el-select v-model="formInline.audioOutId" placeholder="听筒">
          <el-option
            v-for="(item, index) in localDevice.audioOut "
            :key="index"
            :label="item.label"
            :value="item.id"
          />
        </el-select>
      </el-form-item>
      <el-form-item label="分辨率:Width">
        <el-input v-model="formInline.width" />
      </el-form-item>
      <el-form-item label="分辨率:Height">
        <el-input v-model="formInline.height" />
      </el-form-item>
      <el-form-item label="FPS">
        <el-input v-model="formInline.frameRate" />
      </el-form-item>
      <el-form-item>
        <el-button type="primary" @click="openCamera">打开摄像头</el-button>
        <el-button type="primary" @click="closeCamera">关闭摄像头</el-button>
      </el-form-item>
    </el-form>
    <div>
      <video ref="video"></video>
    </div>
  </div>
</template>

<script>
export default {
  name: 'Basis',
  data () {
    return {
      localDevice: {
        audioIn: [],
        videoIn: [],
        audioOut: []
      },
      formInline: {
        videoId: null,
        audioInId: null,
        audioOutId: null,
        width: 1080,
        height: 720,
        frameRate: 24
      }
    }
  },
  created () {
    this.initMediaDevices()
  },
  mounted () {
    this.videoElem = this.$refs.video
  },
  methods: {
    initMediaDevices () {
      if (!navigator.mediaDevices || !navigator.mediaDevices.enumerateDevices) {
        console.log('不支持 enumerateDevices() .')
        return
      }
      navigator.mediaDevices.enumerateDevices().then(devices => {
        const localDevice = {
          audioIn: [],
          videoIn: [],
          audioOut: []
        }
        devices.forEach(device => {
          const obj = { id: device.deviceId, kind: device.kind, label: device.label }
          if (device.kind === 'audioinput') {
            if (localDevice.audioIn.filter(e => e.id === device.deviceId).length === 0) {
              localDevice.audioIn.push(obj)
            }
          } if (device.kind === 'audiooutput') {
            if (localDevice.audioOut.filter(e => e.id === device.deviceId).length === 0) {
              localDevice.audioOut.push(obj)
            }
          } else if (device.kind === 'videoinput') {
            if (localDevice.videoIn.filter(e => e.id === device.deviceId).length === 0) {
              localDevice.videoIn.push(obj)
            }
          }
        })
        this.localDevice = localDevice
      })
    },
    openCamera () {
      this.closeCamera()
      this.getDeviceMedia().then(mediaStream => {
        this.videoElem.srcObject = mediaStream
        this.videoElem.onloadedmetadata = () => {
          this.videoElem.play()
        }
      }).catch(err => {
        console.log(err)
      })
    },
    getDeviceMedia () {
      // const constraints = {
      //   audio: true,
      //   video: {
      //     // 设置分辨率，ideal 权重更高，浏览器会先尝试找到最接近指定的理想值的设定或者摄像头（如果设备拥有不止一个摄像头）
      //     width: { min: 1024, ideal: 1280, max: 1920 },
      //     height: { min: 776, ideal: 720, max: 1080 }
      //     // facingMode: 'user'
      //     // 强制使用后置摄像头
      //     // facingMode: { exact: 'environment' }
      //   }
      // }
      const { videoId, audioId, width, height, frameRate } = this.formInline
      const constraints = {
        audio: { deviceId: audioId ? { exact: audioId } : null },
        video: {
          deviceId: videoId ? { exact: videoId } : null,
          width: width,
          height: height,
          frameRate: { ideal: frameRate, max: 24 }
        }
      }
      return navigator.mediaDevices.getUserMedia(constraints)
    },
    closeCamera () {
      if (this.videoElem.srcObject) {
        const tracks = this.videoElem.srcObject.getTracks()
        tracks.forEach(track => track.stop())
        this.videoElem.srcObject = null
      }
    }
  }
}
</script>

<style lang="scss" scoped>
video {
  width: 400px;
  border: 1px solid #ccc;
}
</style>
